﻿using System;
using Nolineq.Methods;
using ArithmeticLibrary;

namespace Nolineq
{
    /// <summary>
    /// Factory na instance resice rovnic.
    /// </summary>
    public static class MethodFactory
    {
        /// <summary>
        /// Typ metody pro reseni rovnice.
        /// </summary>
        public enum Type
        {
            /// <summary>
            /// Metoda jednoducha.
            /// </summary>
            Jednoducha = 1,
            /// <summary>
            /// Metoda bisekce.
            /// </summary>
            Bisekce = 2,
            /// <summary>
            /// Metoda secen.
            /// </summary>
            RegulaFalsi = 3,
            /// <summary>
            /// Metoda tecen.
            /// </summary>
            Newtonova = 4,
            /// <summary>
            /// Metoda kombinovana
            /// </summary>
            Kombinovana = 5,
            /// <summary>
            /// Metoda damping
            /// </summary>
            Damping = 6,
        }

        /// <summary>
        /// Vytvori resic rovnic.
        /// </summary>
        /// <param name="id">ID metody.</param>
        /// <param name="function">Funkce.</param>
        /// <returns>Vrati instanci resice.</returns>
        public static EquationSolver CreateSolver(Type id, Function function, double start, double end, double root, double precision, int maxSteps)
        {
            switch (id)
            {
                case Type.Jednoducha:
                    return new SimpleMethod(function, start, end, root, precision, maxSteps);
                case Type.Bisekce:
                    return new BisectionMethod(function, start, end, root, precision, maxSteps);
                case Type.RegulaFalsi:
                    return new SecantMethod(function, start, end, root, precision, maxSteps);
                case Type.Newtonova:
                    return new NewtonsMethod(function, start, end, root, precision, maxSteps);
                case Type.Kombinovana:
                    return new NewtonsHybridMethod(NewtonsHybridMethod.SlowMethodType.SecantMethod, 
                        function, start, end, root, precision, maxSteps);
                case Type.Damping:
                    return new NewtonsDampingMethod(function, start, end, root, precision, maxSteps);
                default:
                    throw new Exception("Neznamy typ resitele.");
            }   
        }
    }
}
